package com.alpha.eceasy.mall.service.impl;

import com.alpha.eceasy.exception.ErrorCodeEnum;
import com.alpha.eceasy.mall.api.constant.VerificationCodeRedis;
import com.alpha.eceasy.mall.api.dto.SendEmailDTO;
import com.alpha.eceasy.exception.BizException;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.FileUpload;
import org.apache.tomcat.util.http.fileupload.ProgressListener;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class CommonServiceImpl {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Value("${app.mail.from}") // 从application.yml配置文件中获取
    private String from; // 发送发邮箱地址
    @Resource
    private JavaMailSender mailSender;
    @Value("${app.imgSaveAddress}")
    private String attachmentAddress;

    public Boolean sendEmail(SendEmailDTO sendEmailVO) {
        log.info("sendEmailVO:{}", sendEmailVO);
        if (!StringUtils.isNotBlank(sendEmailVO.getUsername())) {
            throw new BizException(ErrorCodeEnum.USER_NAME_NULL);
        }
        String emailVerifyCode = VerificationCodeRedis.EMAIL_VERIFY_CODE + sendEmailVO.getUsername() + ":";
        if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(emailVerifyCode))) {
            throw new BizException(ErrorCodeEnum.EMAIL_CODE_REPEAT);
        }
        Random ne = new Random();
        String code = String.valueOf(ne.nextInt(9000) + 1000);
        String subject = "注册账号验证码";
        String content = "您注册的验证码为:" + code;
        log.info("验证码:{}", code);
        this.sendMessage(sendEmailVO.getToEmail(), subject, content);
        stringRedisTemplate.opsForValue().set(emailVerifyCode, code, 5, TimeUnit.MINUTES);
        return true;
    }

    /**
     * 发送纯文本邮件信息
     *
     * @param to      接收方
     * @param subject 邮件主题
     * @param content 邮件内容（发送内容）
     */
    public void sendMessage(String to, String subject, String content) {
        // 创建一个邮件对象
        SimpleMailMessage msg = new SimpleMailMessage();
        msg.setFrom(from); // 设置发送发
        msg.setTo(to); // 设置接收方
        msg.setSubject(subject); // 设置邮件主题
        msg.setText(content); // 设置邮件内容
        // 发送邮件
        mailSender.send(msg);
        log.info("邮件发送成功");
    }

    public List<String> uploadImg(HttpServletRequest request, HttpServletResponse response) {

        response.setContentType("application/json;charset=utf-8");

        String uploadPath = "";
//        String uploadPath = "E:\\ecEasy\\video";

//        String uploadPath = property+"\baseframe-main\src\main\resources\static\video";
        uploadPath = attachmentAddress;

        BufferedOutputStream os = null;

        //使用Apache文件上传组件处理文件上传步骤：
        //1、创建一个DiskFileItemFactory工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();
        //设置工厂的缓冲区的大小，当上传的文件大小超过缓冲区的大小时，就会生成一个临时文件存放到指定的临时目录当中。
        factory.setSizeThreshold(1024 * 100);//设置缓冲区的大小为100KB，如果不指定，那么缓冲区的大小默认是10KB
            /*//设置上传时生成的临时文件的保存目录
            factory.setRepository(tmpFile);*/
        //2、创建一个文件上传解析器
        FileUpload upload = new FileUpload();
        upload.setFileItemFactory(factory);
        //监听文件上传进度
        upload.setProgressListener(new ProgressListener() {
            @Override
            public void update(long pBytesRead, long pContentLength, int arg2) {
//                System.out.println("文件大小为：" + pContentLength + ",当前已处理：" + pBytesRead);
            }
        });
        //解决上传文件名的中文乱码
        upload.setHeaderEncoding("UTF-8");
        //3、判断提交上来的数据是否是上传表单的数据
//            if(!ServletFileUpload.isMultipartContent(SellerCreateRequestDTO)){
//                //按照传统方式获取数据
//                return null;
//            }

        //设置上传单个文件的大小的最大值，目前是设置为1024*1024字节，也就是1MB
        upload.setFileSizeMax(1024 * 1024 * 10);
        //设置上传文件总量的最大值，最大值=同时上传的多个文件的大小的最大值的和，目前设置为10MB
        upload.setSizeMax(1024 * 1024 * 30);
        //4、使用ServletFileUpload解析器解析上传数据，解析结果返回的是一个List<FileItem>集合，每一个FileItem对应一个Form表单的输入项
        String nowTimeYear = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        StandardMultipartHttpServletRequest fileRequest = (StandardMultipartHttpServletRequest) request;
        MultiValueMap<String, MultipartFile> fileMap = fileRequest.getMultiFileMap();
        //遍历所有的文件，每个List<MultipartFile>代表一个文件，get(0)就可以了

        List<String> fileList = new ArrayList<>();
        String originalFilename = "test";


        for (Map.Entry<String, List<MultipartFile>> entry : fileMap.entrySet()) {
            List<MultipartFile> value = entry.getValue();
            MultipartFile multipartFile = value.get(0);
            String time = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
            String[] split = UUID.randomUUID().toString().split("-");
            originalFilename = time + split[0];

            uploadPath = uploadPath + nowTimeYear;
            File file = new File(uploadPath);
            if (!file.exists()) {
                // 创建完整的目录
                file.mkdirs();
            }
            String fileSuffix = Objects.requireNonNull(multipartFile.getOriginalFilename()).substring(multipartFile.getOriginalFilename().lastIndexOf("."));
            originalFilename = originalFilename + fileSuffix;
            File tempFile = new File(uploadPath, originalFilename);
            try {
                os = new BufferedOutputStream(Files.newOutputStream(tempFile.toPath()));

                byte[] bytes = multipartFile.getBytes();
                os.write(bytes);
                os.flush();


                os.flush();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            String fileName = "/" + nowTimeYear + "/" + originalFilename;

            fileList.add(fileName);
        }

        String responseName = "/" + nowTimeYear + "/" + originalFilename;


        return fileList;
    }
}
